package cn.dansj.socket;

import cn.dansj.common.request.annotation.http.GetMethod;
import cn.dansj.common.request.annotation.http.PostMethod;
import cn.dansj.common.request.annotation.http.RequestMappingMethod;
import cn.dansj.common.request.annotation.http.RequestParam;
import cn.dansj.common.utils.bean.Return;
import cn.dansj.common.utils.enums.BooleanType;
import cn.dansj.utils.project.SSEUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.async.AsyncRequestNotUsableException;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

@RequestMappingMethod(value = "/sse", nologging = BooleanType.TRUE)
public class SseController {
    private final Logger logger = LoggerFactory.getLogger(SseController.class);

    @GetMethod(value = "/connect", produces = MediaType.TEXT_EVENT_STREAM_VALUE, permission = BooleanType.TRUE)
    public SseEmitter sseConnect(@RequestParam String clientId) {
        return SSEUtils.connect(clientId);
    }

    @PostMethod(value = "/sendMessage")
    public Return<?> send(@RequestParam String clientId, @RequestParam String message, @RequestParam(required = false) String eventName) {
        SSEUtils.sendMessage(clientId, message, eventName);
        return Return.SUCCESS;
    }

    @PostMethod(value = "/removeClient", permission = BooleanType.TRUE)
    public Return<?> removeClient(@RequestParam String clientId) {
        SSEUtils.removeClient(clientId);
        return Return.SUCCESS;
    }

    @GetMethod(value = "/getUserName")
    public Return<?> getUserName() {
        return Return.T(SSEUtils.getUserName());
    }

    @ExceptionHandler
    public void sseConnect(Exception exception, HttpServletRequest httpServletRequest) {
        final String clientId = httpServletRequest.getParameter("clientId");
        logger.info("{}<<<<< clientRemove >>>>>{}>>>>>{}", clientId, exception.getClass().getSimpleName(), exception.getMessage());
        SSEUtils.removeClient(clientId);
    }

    @ExceptionHandler
    public void sseConnect(AsyncRequestNotUsableException exception, HttpServletRequest httpServletRequest) {
        final String clientId = httpServletRequest.getParameter("clientId");
        logger.info("{}<<<<< clientRemove >>>>>{}", clientId, exception.getMessage());
        SSEUtils.removeClient(clientId);
    }
}
